#ifndef _THREAD_UTILS_DEFS_
#define _THREAD_UTILS_DEFS_

#include "recursive_locker.h"

#define DECL_PROPERTIES(CLASS_NAME) private: QHash<QString, QVariant> properties_p; \
    public: inline CLASS_NAME & setProperty(const char * _name, const QVariant & _value) { SAFE_SET(properties_p[_name], _value); return * this; }  \
    inline CLASS_NAME & setProperty_nolock(const char * _name, const QVariant & _value) { properties_p[_name] = _value; return * this; }  \
    inline QVariant property(const char * _name) const { return SAFE_GET(properties_p[_name]); } \
    inline QVariant property_nolock(const char * _name) const { return properties_p[_name]; } \
	inline CLASS_NAME & setProperties(const QHash<QString, QVariant> & _properties) { SAFE_SET(properties_p, _properties); return * this; } \
    inline QHash<QString, QVariant> properties() const { return SAFE_GET(properties_p); }

#ifndef THREAD_UTILS_DISABLED

#define DECL_MUTEX protected: mutable RecursiveLocker rw_lock; \
	inline RecursiveLocker & RecursiveLockForWrite() const { rw_lock.lockForWrite(); return rw_lock; } \
	inline RecursiveLocker & RecursiveLockForRead() const { rw_lock.lockForRead(); return rw_lock; } \
	inline RecursiveLocker & RecursiveUnlock() const { rw_lock.unlock(); return rw_lock; } \
	inline RecursiveLocker & RecursiveLockerRef() const { return rw_lock; }

#define THREAD_SAFETY_ENABLED(__STATE__) RecursiveLockerRef().setEnabled(__STATE__)

#define THREAD_SAFE(_TYPE_)		RecursiveLockFor##_TYPE_();
#define THREAD_UNSAFE			RecursiveUnlock();

template <class T> inline void SafeProperty(T & _property, const T & _value, RecursiveLocker & _lock, bool _already_locked = false)
{
	if (!_already_locked)
	{
		_lock.lockForWrite();
	}
	_property = _value;
	_lock.unlock();
}

template <class T> inline T SafeProperty(const T & _property, RecursiveLocker & _lock, bool _already_locked = false)
{
	if (!_already_locked)
	{
		_lock.lockForRead();
	}
	const T _result = _property;
	_lock.unlock();
	return _result;
}

#define SAFE_SET(_PROPERTY_, _VALUE_) (::SafeProperty(_PROPERTY_, _VALUE_, RecursiveLockForWrite(), true))
#define SAFE_GET(_PROPERTY_) (RecursiveLockForRead().usageMode() ? ::SafeProperty(_PROPERTY_, RecursiveLockerRef(), true) : ::SafeProperty(_PROPERTY_, RecursiveLockerRef(), true))

#else

#define DECL_MUTEX
#define THREAD_SAFETY_ENABLED(__STATE__)
#define THREAD_SAFE(_TYPE_)		
#define THREAD_UNSAFE			
#define SAFE_SET(_PROPERTY_, _VALUE_) _PROPERTY_ = _VALUE_
#define SAFE_GET(_PROPERTY_) _PROPERTY_

#endif

#endif